home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / vol16n13.zip / OPENTR.ZIP / OT_SRC.ZIP / OPENTRAP.CPP < prev    next >
C/C++ Source or Header  |  1997-05-26  |  17KB  |  487 lines

  1. // OpenTrap.cpp : Defines the class behaviors for the application.
  2. //
  3. // OpenTrap Version 1.00 by Gregory A. Wolking
  4. // Copyright ⌐ 1997 Ziff-Davis Publishing
  5. // First published in PC Magazine, US Edition, July 1997.
  6.  
  7. #include "stdafx.h"
  8. #include <afxpriv.h>        //Required for override of OnUpdateRecentFileMenu();
  9. #include "OpenTrap.h"
  10.  
  11. #include "MainFrm.h"
  12. #include "OTDoc.h"
  13. #include "OTView.h"
  14. #include "OTextern.h"
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20.  
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CMyCmdLine class for processing custom command line options
  23. // If a given setting or group of settings was specified on the command line,
  24. // this routine sets all the global variables in that category appropriately
  25. // (either to their defaults, or the value specified on the command line)
  26. // and sets a flag indicating it has done so.
  27. class CMyCmdLine : public CCommandLineInfo
  28. {
  29.     // Functions
  30. public:
  31.     CMyCmdLine();    
  32.     // All we really need is an override of ParseParam
  33.     virtual void ParseParam(LPCTSTR lpsxParam, BOOL bFlag, BOOL bLast);
  34.  
  35.     // Member variables.
  36. public:
  37.     BOOL m_bUninstall;
  38.     BOOL m_bAutoStart;
  39.     BOOL m_bExportOptsSet;
  40.     BOOL m_bLogSizeSet;
  41.     BOOL m_bLogOptsSet;
  42.     BOOL m_bShowNumsSet;
  43.     BOOL m_bFilterOptsSet;
  44. };
  45.  
  46. CMyCmdLine::CMyCmdLine() : CCommandLineInfo()
  47. {
  48.     // Initialize our member variables.
  49.     m_bUninstall        = FALSE;
  50.     m_bAutoStart        = FALSE;
  51.     m_bExportOptsSet    = FALSE;
  52.     m_bLogSizeSet        = FALSE;
  53.     m_bLogOptsSet        = FALSE;
  54.     m_bShowNumsSet        = FALSE;
  55.     m_bFilterOptsSet    = FALSE;
  56. }
  57.  
  58. // Parses individual parameters and sets global variables accordingly.
  59. // Note that this function requires using the function form of toupper()
  60. // so that the pointer "p" gets incremented properly in the switch statements.
  61. void CMyCmdLine::ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast)
  62. {
  63.     const char *p = lpszParam;
  64.  
  65.     if (bFlag)
  66.     {    
  67.         switch ((toupper)(*p++))                    // Test current char, point to next.
  68.         {
  69.         case 'U': m_bUninstall = TRUE; break;        // Uninstall
  70.         case 'A': m_bAutoStart = TRUE; break;        // AutoStart
  71.         case 'E':                                // Export options:
  72.             m_bExportOptsSet = TRUE;
  73.             while (*p)
  74.             {    
  75.                 switch ((toupper)(*p++))            // Test current char, point to next.
  76.                 {
  77.                 case 'R': g_bExportRecNums = TRUE; break;        // Record numbers
  78.                 case 'C': g_bCommaDelimited = TRUE; break;        // Comma-delimited
  79.                 case 'F': g_bWriteFiltered = TRUE;                // Write with filters.
  80.                 }
  81.             }
  82.             break;
  83.         case 'F':                                // Filter Options:
  84.             m_bFilterOptsSet = TRUE;
  85.             switch ((toupper)(*p++))
  86.             {
  87.             case 'B':                        // Base name filter.
  88.                 if (*p)
  89.                 {
  90.                     g_strFilterFileName = p;
  91.                     g_strFilterFileName.MakeUpper();
  92.                 }
  93.                 g_bFilterFileName = !g_strFilterFileName.IsEmpty();
  94.                 break;
  95.             case 'T':                        // Event type
  96.                 while (*p)
  97.                 {
  98.                     switch ((toupper)(*p++))    // Test current char, point to next.
  99.                     {
  100.                     case 'O': g_intFilterEvents = 1; break;        // Opens only.
  101.                     case 'E': g_bFilterErrorsOnly = TRUE;        // Errors only.
  102.                     }
  103.                 }
  104.                 break;
  105.             case 'M':                        // Module Name
  106.                 g_strFilterModuleName = p;
  107.                 g_bFilterModule = TRUE;
  108.                 g_strFilterModuleName = g_strFilterModuleName.Left(8);
  109.                 g_strFilterModuleName.MakeUpper();
  110.                 break;
  111.             case 'E':                        // File Extension
  112.                 g_strFilterFileExt = p;
  113.                 g_strFilterFileExt.MakeUpper();
  114.                 g_bFilterFileExt = TRUE;
  115.             }
  116.             break;
  117.         case 'L':                                // Logging options:
  118.             m_bLogOptsSet = TRUE;
  119.             while (*p)
  120.             {
  121.                 switch ((toupper)(*p++))                        // Test current char, point to next.
  122.                 {
  123.                 case 'H': g_bHide = TRUE; break;                // Hide to system tray.
  124.                 case 'E': g_bLogErrorsOnly = TRUE; break;        // Log errors only.
  125.                 case 'O': g_bLogOpensOnly = TRUE; break;        // Log opens only.
  126.                 case 'A': g_dwWatchVM = LOG_ALL; break;            // Log all apps.
  127.                 case 'D': g_dwWatchVM = LOG_ALL_DOS; break;        // DOS apps only.
  128.                 case 'W': g_dwWatchVM = LOG_WINDOWS_ONLY;        // Win apps only.
  129.                 }
  130.             }
  131.             break;
  132.         case 'B':                                    // Buffer Size.
  133.             m_bLogSizeSet = TRUE;
  134.             g_intLogSizeK = atoi(p);
  135.             if (g_intLogSizeK > 2048) 
  136.                 g_intLogSizeK = 2048;
  137.             else
  138.                 if (g_intLogSizeK < 64) 
  139.                     g_intLogSizeK = 64;
  140.             break;
  141.         case 'R':                                    // Record numbers.
  142.             m_bShowNumsSet = TRUE;
  143.             g_bShowNums = ((toupper)(*p) == 'S');
  144.             break;
  145.         default:    // Call base class if switch was not one of ours.
  146.             CCommandLineInfo::ParseParam(lpszParam, bFlag, bLast);
  147.         }
  148.     }
  149.     else    // Call base class if parm was not a switch.
  150.         CCommandLineInfo::ParseParam(lpszParam, bFlag, bLast);
  151.     if (bLast)    // Once the last parm has been processed,
  152.         if (!m_strFileName.IsEmpty())            // See if filename was specified.
  153.             if (m_strFileName.Find('.') == -1)    // If so, does it contain a "."?
  154.                 m_strFileName += ".otl";        // If not, append extension.
  155. }
  156.  
  157. /////////////////////////////////////////////////////////////////////////////
  158. // COpenTrapApp
  159.  
  160. BEGIN_MESSAGE_MAP(COpenTrapApp, CWinApp)
  161.     //{{AFX_MSG_MAP(COpenTrapApp)
  162.     ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  163.         // NOTE - the ClassWizard will add and remove mapping macros here.
  164.         //    DO NOT EDIT what you see in these blocks of generated code!
  165.     //}}AFX_MSG_MAP
  166.     // Standard file based document commands
  167.     ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  168.     ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
  169.     // Standard print setup command
  170.     ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
  171.     // Intercept File MRU commands.
  172.     ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1, OnUpdateRecentFileMenu)
  173. END_MESSAGE_MAP()
  174.  
  175. /////////////////////////////////////////////////////////////////////////////
  176. // COpenTrapApp construction
  177.  
  178. COpenTrapApp::COpenTrapApp()
  179. {
  180. }
  181.  
  182. /////////////////////////////////////////////////////////////////////////////
  183. // The one and only COpenTrapApp object
  184.  
  185. COpenTrapApp theApp;
  186.  
  187. /////////////////////////////////////////////////////////////////////////////
  188. // COpenTrapApp initialization
  189.  
  190. BOOL COpenTrapApp::InitInstance()
  191. {
  192.     // First, make sure we're running under Win 95.
  193.     if (!Check_Version())
  194.     {
  195.         ::MessageBox(NULL, "This program runs only under Windows 95", "OpenTrap", MB_ICONSTOP);
  196.         return FALSE;
  197.     }
  198.     myAtom = ::GlobalFindAtom("OpenTrap running");
  199.  
  200. // Code allows developer to delete the atom in the Debug version in the
  201. // event that the program terminates abnormally and fails to delete its global atom.
  202. // If you take advantage of this, make _sure_ that no other instances of
  203. // the program are running before answering "Yes" to the "delete it?" prompt.
  204. // Because of the #ifdef directive, this code will not appear in the Release build.
  205. #ifdef _DEBUG
  206.     if (myAtom)
  207.     {
  208.         if (::MessageBox(NULL, "Atom exists, delete it?", "OpenTrap", MB_YESNO) == IDYES)
  209.         {
  210.             GlobalDeleteAtom(myAtom);
  211.             myAtom = 0;
  212.         }
  213.     }
  214. #endif
  215.  
  216.     if (myAtom)
  217.     {
  218.         ::MessageBox(NULL, "OpenTrap is already running.\n", "OpenTrap", MB_OK);
  219.         myAtom = 0;
  220.         return FALSE;
  221.     }
  222.     else
  223.     {
  224.         myAtom = ::GlobalAddAtom("OpenTrap running");
  225.     }
  226.     SetRegistryKey("PC Magazine");
  227.     // Register the application's document templates.  Document templates
  228.     //  serve as the connection between documents, frame windows and views.
  229.     CSingleDocTemplate* pDocTemplate;
  230.     pDocTemplate = new CSingleDocTemplate(
  231.         IDR_MAINFRAME,
  232.         RUNTIME_CLASS(COpenTrapDoc),
  233.         RUNTIME_CLASS(CMainFrame),       // main SDI frame window
  234.         RUNTIME_CLASS(COpenTrapView));
  235.     AddDocTemplate(pDocTemplate);
  236.     pDocTemplate->GetDocString(m_strRegDocType, CDocTemplate::regFileTypeId);
  237.     // Parse command line
  238.     CMyCmdLine cmdInfo;
  239.     ParseCommandLine(cmdInfo);
  240.     if (cmdInfo.m_bUninstall)                        // If uninstall was specified,
  241.     {
  242.         if (::MessageBox(NULL,                        // Ask user if he that's what
  243.             "Uninstall option (/U) specified.\n\n"    // he really wants.
  244.             "This will remove all of OpenTrap's\n"
  245.             "data from the Registry.\n\n"
  246.             "Are you sure you wish to proceed?",
  247.             "OpenTrap", MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES)
  248.         {
  249.             m_bUninstall = TRUE;                    // If so, set flag and
  250.             return FALSE;                            // exit application.
  251.         }
  252.         else                                        // Otherwise, launch normally.
  253.             ::MessageBox(NULL, "Uninstall cancelled.", "OpenTrap", MB_OK);
  254.     }
  255.     LoadStdProfileSettings(4);  // Load standard INI file options (including MRU)
  256.     // If a specific setting or group of settings was not specified
  257.     // on the command line, load them from the Registry.
  258.     if (!cmdInfo.m_bLogSizeSet)
  259.         g_intLogSizeK = GetProfileInt(g_szLogKey, "BufferSizeK", 64);
  260.     if (!cmdInfo.m_bLogOptsSet)
  261.     {
  262.         g_bLogErrorsOnly = GetProfileInt(g_szLogKey, "LogErrorsOnly", FALSE);
  263.         g_dwWatchVM = GetProfileInt(g_szLogKey, "WatchVMs", LOG_ALL);
  264.         g_bLogOpensOnly = GetProfileInt(g_szLogKey, "LogActions", FALSE);
  265.         g_bHide = GetProfileInt(g_szLogKey, "UseTaskBar", FALSE);
  266.     }
  267.     if (!cmdInfo.m_bShowNumsSet)
  268.         g_bShowNums = GetProfileInt(g_szViewKey, "ShowNums", FALSE);
  269.     if (!cmdInfo.m_bExportOptsSet)
  270.     {
  271.         g_bExportRecNums = GetProfileInt(g_szExportKey, "RecNums", FALSE);
  272.         g_bCommaDelimited = GetProfileInt(g_szExportKey, "Delimited", FALSE);
  273.         g_bWriteFiltered = GetProfileInt(g_szExportKey, "Filtered", FALSE);
  274.     }
  275.     if (!cmdInfo.m_bFilterOptsSet)
  276.     {
  277.         g_bFilterFileName = GetProfileInt(g_szViewKey, "UseBase", FALSE);
  278.         g_strFilterFileName = GetProfileString(g_szViewKey, "Base", "");
  279.         g_bFilterFileExt = GetProfileInt(g_szViewKey, "UseExt", FALSE);
  280.         g_strFilterFileExt = GetProfileString(g_szViewKey, "Ext", "");
  281.         g_bFilterModule = GetProfileInt(g_szViewKey, "UseModule", FALSE);
  282.         g_strFilterModuleName = GetProfileString(g_szViewKey, "Module", "");
  283.         g_intFilterEvents = GetProfileInt(g_szViewKey, "Events", 0);
  284.         g_bFilterErrorsOnly = GetProfileInt(g_szViewKey, "Errors", FALSE);
  285.     }
  286.     RegisterShellFileTypes(TRUE);        // Set association for .OTL files.
  287.     EnableShellOpen();                // Allow launching .OTL files from Explorer.
  288.     // Dispatch commands specified on the command line
  289.     if (!ProcessShellCommand(cmdInfo))
  290.         return FALSE;
  291.     g_hWndMainFrame = m_pMainWnd->m_hWnd;
  292.     // If /S specified, post message to start logging immediately.
  293.     if (cmdInfo.m_bAutoStart)
  294.         ::PostMessage(m_pMainWnd->m_hWnd, WM_COMMAND, ID_LOGGING_START, 0);
  295.     return TRUE;
  296. }
  297.  
  298. /////////////////////////////////////////////////////////////////////////////
  299. // CAboutDlg dialog used for App About
  300.  
  301. class CAboutDlg : public CDialog
  302. {
  303. public:
  304.     CAboutDlg();
  305.  
  306. // Dialog Data
  307.     //{{AFX_DATA(CAboutDlg)
  308.     enum { IDD = IDD_ABOUTBOX };
  309.     //}}AFX_DATA
  310.  
  311.     // ClassWizard generated virtual function overrides
  312.     //{{AFX_VIRTUAL(CAboutDlg)
  313.     protected:
  314.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  315.     //}}AFX_VIRTUAL
  316.  
  317. // Implementation
  318. protected:
  319.     //{{AFX_MSG(CAboutDlg)
  320.         // No message handlers
  321.     //}}AFX_MSG
  322.     DECLARE_MESSAGE_MAP()
  323.  
  324. };
  325.  
  326. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  327. {
  328.     //{{AFX_DATA_INIT(CAboutDlg)
  329.     //}}AFX_DATA_INIT
  330. }
  331.  
  332. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  333. {
  334.     CDialog::DoDataExchange(pDX);
  335.     //{{AFX_DATA_MAP(CAboutDlg)
  336.     //}}AFX_DATA_MAP
  337. }
  338.  
  339. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  340.     //{{AFX_MSG_MAP(CAboutDlg)
  341.         // No message handlers
  342.     //}}AFX_MSG_MAP
  343. END_MESSAGE_MAP()
  344.  
  345. // App command to run the dialog
  346. void COpenTrapApp::OnAppAbout()
  347. {
  348.     CAboutDlg aboutDlg;
  349.     aboutDlg.DoModal();
  350. }
  351.  
  352. /////////////////////////////////////////////////////////////////////////////
  353. // COpenTrapApp commands
  354.  
  355. int COpenTrapApp::ExitInstance() 
  356. {
  357.     if (g_pBufferStart != NULL)        // If buffer is still allocated,
  358.     {
  359.         delete [] g_pBufferStart;    // release it.
  360.         g_pBufferStart = NULL;
  361.     }
  362.     if (myAtom)                        // Delete atom used to detect multiple instances.
  363.         ::GlobalDeleteAtom(myAtom);
  364.     if (!m_bUninstall)                // If uninstall not specified, save settings.
  365.     {
  366.         WriteProfileInt(g_szViewKey, "ShowNums", g_bShowNums);
  367.         WriteProfileInt(g_szExportKey, "RecNums", g_bExportRecNums);
  368.         WriteProfileInt(g_szExportKey, "Delimited", g_bCommaDelimited);
  369.         WriteProfileInt(g_szExportKey, "Filtered", g_bWriteFiltered);
  370.     }
  371.     else
  372.     {
  373.         Do_Uninstall();
  374.     }
  375.     return CWinApp::ExitInstance();
  376. }
  377.  
  378. BOOL COpenTrapApp::Check_Version(void)
  379. {
  380.     OSVERSIONINFO vi;
  381.  
  382.     vi.dwOSVersionInfoSize = sizeof(vi);
  383.     GetVersionEx(&vi);
  384.     return (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
  385. }
  386.  
  387. // Handles uninstall.
  388. void COpenTrapApp::Do_Uninstall(void)
  389. {
  390.     HKEY base_key;
  391.     LONG result;
  392.     unsigned char buf[256];
  393.     DWORD chars_read, reg_type;
  394.     BOOL flag;
  395.  
  396.     // Open registry key for PC Mag utils.
  397.     result = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\PC Magazine", 0, KEY_ALL_ACCESS, &base_key);
  398.     if (SUCCEEDED(result))
  399.     {
  400.         result |= RegDeleteKey(base_key, "OpenTrap");        // Delete our settings.
  401.         result |= RegCloseKey(base_key);
  402.         if (SUCCEEDED(result))                                // If ok so far,
  403.         {                                                    // Check file association.
  404.             result = RegOpenKeyEx(HKEY_CLASSES_ROOT, ".otl", 0, KEY_QUERY_VALUE, &base_key);
  405.             if (SUCCEEDED(result))
  406.             {
  407.                 chars_read = 256;                            // Retrieve default file type string.
  408.                 result = RegQueryValueEx(base_key, "", 0, ®_type, buf, &chars_read);
  409.                 if (SUCCEEDED(result))
  410.                 {
  411.                     RegCloseKey(base_key);                    // Is it the correct string?
  412.                     flag = m_strRegDocType.CompareNoCase((const char *) buf) == 0;
  413.                     if (!flag)                                // Ask user if he wants to remove
  414.                         flag =    ::MessageBox(NULL,             // The association.
  415.                                 "The .OTL extension is apparently associated\n"
  416.                                 "with a different application. Do you wish to\n"
  417.                                 "remove the association anyway?",
  418.                                 "Uninstall OpenTrap",
  419.                                 MB_ICONQUESTION | MB_YESNO) == IDYES;
  420.                     if (flag)                                // If user said yes, remove the association.
  421.                     {
  422.                         result |= RegDeleteKey(HKEY_CLASSES_ROOT, ".otl");
  423.                         result |= RegDeleteKey(HKEY_CLASSES_ROOT, m_strRegDocType);
  424.                     }
  425.                     else
  426.                         result = 0;                            // Otherwise indicate success.
  427.                 }
  428.                 else
  429.                 {
  430.                     RegCloseKey(base_key);                    // Make sure the key is closed!
  431.                 }
  432.             }
  433.         }
  434.     }
  435.     if (SUCCEEDED(result))            // Report sucess or failure.
  436.     {
  437.         ::MessageBox(NULL,
  438.             "Uninstall successful. You may\n"
  439.             "now delete OpenTrap's files\n"
  440.             "from your hard disk\n\n"
  441.             "Be sure to delete any shortcuts to\n"
  442.             "OPENTRAP.EXE that you may have created!", "OpenTrap", MB_ICONINFORMATION | MB_OK);
  443.         ::MessageBox(NULL,
  444.             "IMPORTANT NOTE: If you also have the PC Magazine\n"
  445.             "Utility \"BigBin\" installed on your system,\n"
  446.             "do NOT delete the FUNCTRAP.VXD device driver\n"
  447.             "or BigBin will be unable to function.", "OpenTrap", MB_ICONSTOP | MB_OK);
  448.     }
  449.     else
  450.         ::MessageBox(NULL, "Uninstall failed.", "OpenTrap", MB_ICONSTOP);
  451. }
  452.  
  453. // Handles File MRU list update. Frankly, this is sneaky.
  454. // The MFC framework has built-in support for the MRU
  455. // list, but it doesn't provide for disabling the MRU entries if
  456. // their use is not appropriate in the program's current state.
  457. // In our case, we need to disable the File MRU commands while logging
  458. // is in progress.
  459. //
  460. // Unlike other menu commands, you cannot use a standard
  461. // OnUpdate() handler to control the MRU entries.
  462. // None of this stuff is documented, so I spent quite a bit of
  463. // time digging through the MFC core code to figure out how to do this.
  464. // The CWinApp class includes the protected member variable m_pRecentFileList,
  465. // which is a pointer to an object of Class "CRecentFileList".
  466. // That class is also not documented, but if you let MFC do its thing with the
  467. // MRU list, the m_nSize member variable indicates the number of entries in the
  468. // list, as established by the CWinApp::LoadStdProfileSettings() member function.
  469. // The m_arrNames[] member variable is an array of CStrings. If the first element
  470. // in the array is empty, the entire MRU list is empty. If any other element of the
  471. // array is empty, there is no corresponding File MRU command on the menu.
  472. void COpenTrapApp::OnUpdateRecentFileMenu(CCmdUI* pCmdUI)
  473. {
  474.     // Call base class to update the MRU list and enable all the items.
  475.     // The mechanism maintains the m_arrNames[] array so that it is always
  476.     // "packed"; the MRU file names are stored contiguously beginning
  477.     // with the first CString in the array (m_arrNames[0]).
  478.     CWinApp::OnUpdateRecentFileMenu(pCmdUI);
  479.     // If we're logging,
  480.     if (g_bIsLogging)
  481.         // Disable each existing File MRU command.
  482.         for (int i = 0;
  483.             i < m_pRecentFileList->m_nSize && !m_pRecentFileList->m_arrNames[i].IsEmpty();
  484.             i++)
  485.             pCmdUI->m_pMenu->EnableMenuItem(ID_FILE_MRU_FILE1 + i, MF_GRAYED);
  486. }
  487.